#include <iostream>  
#include <string>  
#include <map>
#include <cstdio>
#include <cstdlib>
#include "kdtree.h"  
#include "HogFontFeatureExtractor.h"
#include "codecvt.h"

#define MAX_DIM 968

void Query();

int main(int argc, char* argv[])  
{  
  Query();  
  return 0;  
}  

unsigned int Line2Feature(char *str, double* f) {
  std::string charCode(str, 4);
  unsigned int r = strtol(charCode.c_str(), NULL, 16);

  char *start = str + 5;
  char *comma = start;
  int i = 0;

  while(*comma) {
    while(*comma != '\n' && *comma != ',') ++comma;
    std::string t(start, comma-start);
    f[i++] = atof(t.c_str());
    start = comma + 1;
    comma = start;
  }

  return r;
}
double dist_sq( double *a1, double *a2, int dims ) {
  double dist_sq = 0, diff;
  while( --dims >= 0 ) {
    diff = (a1[dims] - a2[dims]);
    dist_sq += diff*diff;
  }
  return dist_sq;
}
void Query()  
{  
  //创建数据  
  FILE* fp = fopen("../conf/features", "r");

  static char buffer[1024*1024] = { 0 };
  static unsigned int charCodes[0x8000] = { 0 };
  std::map<unsigned int, double*> manager;
  kdtree* kd = kd_create(MAX_DIM);

  int count = 0;

  printf("Loading features...\n");

  while(fgets(buffer, 1024*1024, fp)) {
    double *f = new double[MAX_DIM]; 

    charCodes[count] = Line2Feature(buffer, f);
    kd_insert(kd, f, &charCodes[count]);
    manager[charCodes[count]] = f;
    ++count;
  }
  fclose(fp);

  printf("Loading successfully!\n");


  static double pos[MAX_DIM] = { 0 };
  static double tmp[MAX_DIM] = { 0 };
  unsigned char utf8[8] =  { 0 };
  double *t = NULL;
  std::vector<double> feature;
  HogFontFeatureExtractor ffe;

  while (true)  
  {  
    unsigned int charCode = 0;
    printf("please input Chinese character:");
    scanf("%s", utf8);
    Utf82Unicode(utf8, &charCode);
    printf("unicode = %04x\n", charCode);

  
    
    if (manager.find(charCode) == manager.end()) {
      if (ffe.GetFeature(charCode, &feature)) {
        for (size_t i = 0; i < feature.size(); ++i) {
          tmp[i] = feature[i];
        }
        t = tmp;
      }
      else {
        printf("无效值: %04x\n", charCode);
        printf("\x1b[1A");
        continue;
      }
    }
    else {
      t = manager[charCode];
    }
    struct kdres *set =  kd_nearest_n(kd, t, 21);

    while(!kd_res_end(set)) {
      unsigned int *code = (unsigned int*)kd_res_item(set, pos);
      Unicode2Utf8(*code, utf8, 8);
      printf("%04x, %s, dist = %f\n", *code, utf8, sqrt(dist_sq(t, pos, MAX_DIM)));
      kd_res_next(set);
    }

    printf("\n");
    kd_res_free(set);
  }  

  kd_free(kd);
}  
